package system

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/gogf/gf/v2/os/gtime"
	"server/internal/dao"
	"server/internal/model"
	"server/internal/model/do"
	"server/internal/model/entity"
	"server/internal/service"
)

type sSystemLogin struct {
}

func init() {
	service.RegisterSystemLogin(&sSystemLogin{})
}

// Login 用户账号密码登录
func (s *sSystemLogin) Login(ctx context.Context, in model.SystemUserLoginInput) (token string, err error) {
	//查询用户
	adminInfo := new(entity.SystemUser)
	err = dao.SystemUser.Ctx(ctx).Where(do.SystemUser{Username: in.Username}).Scan(adminInfo)
	if gerror.Is(err, sql.ErrNoRows) {
		return "", gerror.New("用户不存在")
	}

	//验证密码
	password, _ := service.SystemUser().EncryptPassword(in.Password)
	fmt.Println(in)
	fmt.Println(in.Password)
	fmt.Println(password)
	fmt.Println(adminInfo)
	if password != adminInfo.Password {
		return "", gerror.New("密码错误")
	}

	return s.handleLoginEvent(ctx, adminInfo)
}

// PhoneSmsCodeLogin 手机号短信验证码登录
func (s *sSystemLogin) PhoneSmsCodeLogin(ctx context.Context, phone string, code string) (token string, err error) {
	//查询用户
	adminInfo := new(entity.SystemUser)
	err = dao.SystemUser.Ctx(ctx).Where(do.SystemUser{Phone: phone}).Scan(adminInfo)
	if gerror.Is(err, sql.ErrNoRows) {
		return "", gerror.New("用户不存在")
	}

	//查询登录验证码 TODO...

	return s.handleLoginEvent(ctx, adminInfo)
}

// handleLoginEvent 处理验证登录通过后用户数据缓存
func (s *sSystemLogin) handleLoginEvent(ctx context.Context, adminInfo *entity.SystemUser) (token string, err error) {
	token, err = service.SystemSession().GetSessionID(ctx)
	if err != nil {
		return "", err
	}

	//设置登录session
	adminInfo.RememberToken = token
	err = service.SystemSession().SetUser(ctx, adminInfo)
	if err != nil {
		return "", err
	}

	//更新token数据
	_, err = dao.SystemUser.Ctx(ctx).Data(do.SystemUser{
		RememberToken: token,
		Ip:            ghttp.RequestFromCtx(ctx).GetClientIp(),
		LoginAt:       gtime.Now(),
	}).Where(do.SystemUser{Id: adminInfo.Id}).Update()
	if err != nil {
		return "", err
	}

	//缓存登录信息和登录用户权限数据，数据存在redis是为了方便切换授权方式（jwt|session）
	err = service.SystemAuthorityCache().SetUserCacheAuthData(ctx, int64(adminInfo.Id))
	if err != nil {
		return "", err
	}

	return token, err
}

func (s *sSystemLogin) Logout(ctx context.Context) (err error) {
	//删除用户缓存数据
	service.SystemAuthorityCache().RemoveUserCacheAuthData(ctx, service.SystemLogin().GetAdminID(ctx))

	//删除session数据
	err = service.SystemSession().RemoveAll(ctx)
	if err != nil {
		return err
	}

	return nil
}

// GetAdminID 解析登录用户信息ID
func (s *sSystemLogin) GetAdminID(ctx context.Context) (userId int64) {
	return service.SystemSession().GetLoginAdminID(ctx)
}

// GetAdminUsername 解析登录用户信息用户名
func (s *sSystemLogin) GetAdminUsername(ctx context.Context) (username string) {
	return service.SystemSession().GetLoginAdminUsername(ctx)
}

func (s *sSystemLogin) GetAdminInfo(ctx context.Context) (admin *entity.SystemUser, err error) {
	return service.SystemSession().GetUser(ctx)
}
